using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace XGAE.Framework.Extensions
{
    public class XmlDataTree
    {
        List<XmlDataTree> branches = new List<XmlDataTree>();

        public List<XmlDataTree> Branches
        {
            get { return this.branches; }
            set { this.branches = value; }
        }

        List<string> leaves = new List<string>();

        public List<string> Leaves
        {
            get { return this.leaves; }
            set { this.leaves = value; }
        }

        public string Name
	    {
            get
            {
                if (leaves.Count > 0)
                    return leaves[0];
                else
                    return string.Empty;
            }
	    }

        public XmlDataTree()
        {
        }

        public XmlDataTree(string filename)
        {
            XmlDocument doc = new XmlDocument();
            try
            {
                // load the architecture definition XML file from the right directory	
                doc.Load(filename);
            }
            catch(Exception ex)
            {
                //throw Exception("There is no such file " + filename, __FILE__, __LINE__);
            }            

	        try
	        {
                // fetch the base node of the DOM tree and recursively traverse it
	            RecurseLoadData(doc.DocumentElement, this);
	        }
             // in this case, it's most likely the user edited the XML file wrong
	        catch (Exception ex)
	        {
	            // FIXME: this doesn't carry the filename, hard to pinpoint
		        //throw fear::Exception( string("Parsing error: ") + e.GetErrorMessage(), "<string>", e.GetLine() );
	        } 
        }

        public XmlDataTree(string k, string v)
        {
            this.leaves.Add(k);
            this.leaves.Add(v);
        }

        void RecurseLoadData(XmlNode node, XmlDataTree dataTree)
        {
            if (node.Name != string.Empty)
                dataTree.Leaves.Add(node.Name);

            foreach(XmlNode childNode in node.ChildNodes)
            {
                switch(childNode.NodeType)
                {
                    case XmlNodeType.CDATA:
                        if(childNode.Value != string.Empty)
                            dataTree.Leaves.Add(childNode.Value);
                        break;
                    case XmlNodeType.Attribute:
                        dataTree.Branches.Add(new XmlDataTree(childNode.Name, childNode.Value));
                        break;
                    case XmlNodeType.Element:
                        dataTree.Branches.Add(new XmlDataTree());
                        RecurseLoadData(childNode, dataTree.Branches[0]);
                        break;
                    default:
                        break;
                }
            }
        }

        public string GetSecondLeaveByKey(string key) // in place of [] operator from C++ version
        {
            foreach (XmlDataTree b in Branches)
            {
                if (b.Leaves.Count > 0 && b.Leaves[0] == key)
                    return b.leaves[1];
            }

            return string.Empty;
        }

        public Extensions.XmlDataTree GetBranchByKey(string key) // in place of () operator from C++ version
        {
            foreach (XmlDataTree b in Branches)
            {
                if (b.Leaves[0] == key)
                    return b;
            }

            return this;
        }
    }
}
